#-*- coding:UTF-8 -*-

from .util import get_argument, get_arguments

from ..logger import logger
from ..config import PLATMGT_HOME, get_property
from ..orm.models import *
from ..orm.db_util import get_objects, count_object, get_object_by_id, \
                        save_object, delete_object, get_resources, get_actors
from ..ldap import user_existed


def add_user(handler):
    logger.debug('model_util.add_user')
    name, fullname = get_argument(handler, 'user_name', 'user_fullname')
    group_id_list = get_arguments(handler, 'user_groups')
    if not user_existed(name):
        return {'status':False, 'cause':'User does not exist in LDAP and please create it in LDAP firstly.'}
    if count_object(User, name=name) > 0:
        return {'status':False, 'cause':'User(%s) has existed in DB'%name}
    logger.debug('name = %s, fullname = %s, group_list = %s'%(name, fullname, group_id_list))
    cur_time=datetime.datetime.now()
    user = User(name=name, fullname=fullname, createtime=cur_time, updatetime=cur_time)
    user_group_mapping_list = []
    for group_id in group_id_list:
        group = get_object_by_id(Group, group_id)
        if group:
            user_group_mapping_list.append(
                UserGroupMapping(user=user, group=group, createtime=cur_time, updatetime=cur_time))
    user.usergroups = user_group_mapping_list
    if save_object(user):
        return {'status':True, 'cause':''}
    else:
        return {'status':False, 'cause':'Failed to create user in DB and please check log.'}


def add_group(handler):
    logger.debug('model_util.add_group')
    name, desc = get_argument(handler, 'group_name', 'group_description')
    user_id_list = get_arguments(handler, 'group_members')
    logger.debug('name = %s, desc = %s, user_id_list = %s'%(name, desc, user_id_list))
    if count_object(Group, name=name) > 0:
        return {'status':False, 'cause':'Group(%s) has existed in DB'%name}
    cur_time=datetime.datetime.now()
    group = Group(name=name, description=desc, createtime=cur_time, updatetime=cur_time)
    group_user_mapping_list = []
    for user_id in user_id_list:
        user = get_object_by_id(User, user_id)
        if user:
            group_user_mapping_list.append(
                UserGroupMapping(user=user, group=group, createtime=cur_time, updatetime=cur_time))
    group.groupusers = group_user_mapping_list
    if save_object(group):
        return {'status':True, 'cause':''}
    else:
        return {'status':False, 'cause':'Failed to create Group in DB and please check log.'}


def update_group(handler):
    logger.debug('model_util.update_group')
    group_id, name, desc = get_argument(handler, 'group_id', 'group_name', 'group_description')
    user_id_list = get_arguments(handler, 'group_members')
    logger.debug('id = %s, name = %s, desc = %s, user_id_list = %s'%(group_id, name, desc, user_id_list))
    group = get_object_by_id(Group, group_id, attr_list=['groupusers.user'])
    if group:
        cur_time=datetime.datetime.now()
        for gu in group.groupusers:
            if str(gu.user.id) in user_id_list:
                user_id_list.remove(str(gu.user.id))
            else:
                delete_object(gu)
        for user_id in user_id_list:
            user = get_object_by_id(User, user_id)
            if user:
                save_object(
                    UserGroupMapping(user=user, group=group,  createtime=cur_time, updatetime=cur_time))
    group.name = name
    group.description = desc
    group.updatetime = cur_time
    save_object(group)
    return {'status':True}


def add_datacenter(handler):
    logger.debug('model_util.add_datacenter')
    name, bandwidth, phone, address = get_argument(handler, 'datacenter_name', 'datacenter_bandwidth', 'datacenter_phone', 'datacenter_address')
    logger.debug('name = %s, bandwidth = %s, phone = %s, address = %s'%(name, bandwidth, phone, address))
    if count_object(DataCenter, name=name) > 0:
        return {'status':False, 'cause':'DataCenter(%s) has existed in DB'%name}
    cur_time=datetime.datetime.now()
    dc = DataCenter(name=name, bandwidth=bandwidth, phone=phone, address=address, createtime=cur_time, updatetime=cur_time)
    if save_object(dc):
        return {'status':True, 'cause':''}
    else:
        return {'status':False, 'cause':'Failed to create DataCenter in DB and please check log.'}


def update_datacenter(handler):
    logger.debug('model_util.update_datacenter')
    dc_id, name, bandwidth, phone, address = get_argument(handler, 'datacenter_id', 'datacenter_name', 'datacenter_bandwidth', 'datacenter_phone', 'datacenter_address')
    mem_host_id_list, alone_host_id_list = get_arguments(handler, 'datacenter_hosts', 'standalone_hosts')
    logger.debug('id = %s, name = %s, bandwidth = %s, phone = %s, address = %s'%(dc_id, name, bandwidth, phone, address))
    dc = get_object_by_id(DataCenter, dc_id, attr_list=['hosts'])
    if dc:
        dc.name = name
        dc.bandwidth = bandwidth
        dc.phone = phone
        dc.address = address
        dc.updatetime = datetime.datetime.now()
        del_list = []
        for host in dc.hosts:
            if str(host.id) not in mem_host_id_list:
                del_list.append(host)
            else:
                mem_host_id_list.remove(str(host.id))
        for host in del_list:
            host.datacenter_id = None
            save_object(host)
        for host_id in mem_host_id_list:
            host = get_object_by_id(Host, host_id)
            host.datacenter_id = dc.id
            save_object(host)
        return {'status':True, 'cause':''}
    return {'status':False, 'cause':'Failed to Update DataCenter in DB and please check log.'}


def add_system(handler):
    logger.debug('model_util.add_system')
    name, desc, systype, enabled = get_argument(handler, 'system_name', 'system_description', 'system_systemtype', 'system_enabled')
    host_id_list = get_arguments(handler, 'system_members')
    if enabled == 'on':
        enabled = 1
    else:
        enabled = 0
    logger.debug('name = %s, desc = %s, system type = %s, host_id_list = %s, enabled = %s'%(name, desc, systype, host_id_list, enabled))
    if count_object(System, name=name) > 0:
        return {'status':False, 'cause':'System(%s) has existed in DB'%name}
    cur_time=datetime.datetime.now()
    s = System(name=name, description=desc, systype=systype, enabled=enabled, createtime=cur_time, updatetime=cur_time)
    if save_object(s):
        s = get_objects(System, name=name)[0]
        for host_id in host_id_list:
            host = get_object_by_id(Host, host_id)
            print '--------------------',s
            print '--------------------',s.id
            #host.system = s
            host.system_id = s.id
            save_object(host)
        return {'status':True, 'cause':''}
    else:
        return {'status':False, 'cause':'Failed to create System in DB and please check log.'}


def update_system(handler):
    logger.debug('model_util.update_system')
    sys_id, name, desc, systype, enabled = get_argument(handler, 'sys_id', 'system_name', 'system_description', 'system_systemtype', 'system_enabled')
    host_id_list = get_arguments(handler, 'system_members')
    #new_host_id_list = handler.get_arguments('system_new_members')
    enabled = handler.get_argument('', '')
    logger.debug('name = %s, desc = %s, system type = %s, host_id_list = %s, enabled = %s'%(name, desc, systype, host_id_list, enabled))
    sys_obj = get_object_by_id(System, sys_id, attr_list=['systemhosts.host'])
    if sys_obj:
        sys_obj.name = name
        sys_obj.description = desc
        sys_obj.systype = systype
        del_list = []
        for syshost in sys_obj.systemhosts:
            if str(syshost.host.id) in host_id_list:
                host_id_list.remove(str(host.id))
            else:
                del_list.append(syshost)
        for syshost in del_list:
            delete_object(syshost)
        cur_time=datetime.datetime.now()
        for host_id in host_id_list:
            syshost = SystemHostMapping(system_id=sys_obj.id, host_id=host_id, createtime=cur_time, updatetime=cur_time)
            save_object(syshost)
        return {'status':True, 'cause':''}
    else:
        return {'status':False, 'cause':'Failed to create System in DB and please check log.'}


def add_host(handler):
    logger.debug('model_util.add_host')
    ip, otherips, hostname, servertype, ostype, dc_id, enabled = get_argument(handler, 'host_ip', 'host_otherips', 'host_hostname', 'host_servertype', 'host_ostype', 'host_datacenter', 'host_enabled')
    if enabled == 'on':
        enabled = 1
    else:
        enabled = 0
    logger.debug('ip = %s, otherips = %s, hostname = %s, servertype = %s, ostype = %s, dc_id = %s, enabled = %s'%(ip, otherips, hostname, servertype, ostype, dc_id, enabled))
    cur_time=datetime.datetime.now()
    dc = get_object_by_id(DataCenter, dc_id)
    host = Host(ip=ip, name=hostname, otherips=otherips,servertype=servertype, ostype=ostype, enabled=enabled, createtime=cur_time, updatetime=cur_time)
    if dc:
        host.datacenter = dc
    if save_object(host):
        return {'status':True, 'cause':''}
    else:
        return {'status':False, 'cause':'Failed to create Host in DB and please check log.'}


def update_host(handler):
    logger.debug('model_util.update_host')
    host_id, ip, otherips, hostname, servertype, ostype, dc_id, enabled = \
        get_argument(handler, 'host_id', 'host_ip', 'host_otherips', 'host_hostname', \
            'host_servertype', 'host_ostype', 'host_datacenter', 'host_enabled')
    logger.debug('id = %s, ip = %s, otherips = %s, hostname = %s, servertype = %s, ostype = %s, dc_id = %s, enabled = %s'%(host_id, ip, otherips, hostname, servertype, ostype, dc_id, enabled))
    cur_time=datetime.datetime.now()
    host = get_object_by_id(Host, host_id)
    if host:
        host.ip, host.otherips, host.name, host.servertype, host.ostype, host.datacenter_id = ip, otherips, hostname, servertype, ostype, dc_id
        if enabled == 'on':
            host.enabled = 1
        else:
            host.enabled = 0
        host.updatetime = cur_time
        if save_object(host):
            return {'status':True, 'cause':''}
    return {'status':False, 'cause':'Failed to create Host in DB and please check log.'}


def add_osuser(handler):
    logger.debug('model_util.add_osuser')
    host_id, username, password = \
        get_argument(handler, 'host_id', 'username', 'password')
    print 'add_osuser password = ',password
    cur_time=datetime.datetime.now()
    auth = Auth(username=username, password=password, 
        createtime=cur_time, updatetime=cur_time)
    auth.host_id = host_id
    if save_object(auth):
        return {'status':True, 'cause':''}
    return {'status':False, 
        'cause':'Failed to create Host in DB and please check log.'}


def update_osuser(handler):
    logger.debug('model_util.update_osuser')
    auth_id, username, password = \
        get_argument(handler, 'auth_id', 'username', 'password')
    print 'update_osuser password = ',password
    auth = get_object_by_id(Auth, auth_id)
    if auth:
        auth.username = username
        auth.password = password
        auth.updatetime = datetime.datetime.now()
        if save_object(auth):
            return {'status':True, 'cause':''}
    return {'status':False, 
        'cause':'Failed to create Host in DB and please check log.'}


def change_system_perm(handler):
    logger.debug('model_util.change_system_perm')
    sys_id = get_argument(handler, 'sys_id')
    sel_group_id_list = get_arguments(handler, 'group_list')
    sel_user_id_list  = get_arguments(handler, 'user_list')
    sys_obj = get_object_by_id(System, sys_id)
    group_list = get_actors(System, sys_id, Group)
    user_list  = get_actors(System, sys_id, User)
    del_group_list, del_user_list = [], []
    cur_time=datetime.datetime.now()
    #mapping betweeen system and group
    for group in group_list:
        if str(group.id) in sel_group_id_list:
            sel_group_id_list.remove(str(group.id))
        else:
            del_group_list.append(group)
    for sel_group_id in sel_group_id_list:
        save_object(PermissionMapping(createtime=cur_time, updatetime=cur_time,\
            actor_type=Group.__name__, actor_id=sel_group_id,\
            res_type=System.__name__, res_id=sys_id))
    for group in del_group_list:
        query_objs = get_objects(PermissionMapping, \
            actor_type=Group.__name__, actor_id=group.id, \
            res_type=System.__name__, res_id=sys_id)
        if len(query_objs) == 1:
            delete_object(query_objs[0])
    #mapping betweeen system and user
    for user in user_list:
        if str(user.id) in sel_user_id_list:
            sel_user_id_list.remove(str(user.id))
        else:
            del_user_list.append(user)
    for sel_user_id in sel_user_id_list:
        save_object(PermissionMapping(createtime=cur_time, updatetime=cur_time,\
            actor_type=User.__name__, actor_id=sel_user_id, \
            res_type=System.__name__, res_id=sys_id))
    for user in del_user_list:
        query_objs = get_objects(PermissionMapping, \
            actor_type=User.__name__, actor_id=user.id, \
            res_type=System.__name__, res_id=sys_id)
        if len(query_objs) == 1:
            delete_object(query_objs[0])
    return {'status':True, 'cause':''}


def change_host_perm(handler):
    logger.debug('model_util.change_host_perm')
    host_id = get_argument(handler, 'host_id')
    sel_group_id_list = get_arguments(handler, 'group_list')
    sel_user_id_list  = get_arguments(handler, 'user_list')
    host = get_object_by_id(Host, host_id)
    group_list = get_actors(Host, host_id, Group)
    user_list  = get_actors(Host, host_id, User)
    del_group_list, del_user_list = [], []
    cur_time=datetime.datetime.now()
    #mapping betweeen host and group
    for group in group_list:
        if str(group.id) in sel_group_id_list:
            sel_group_id_list.remove(str(group.id))
        else:
            del_group_list.append(group)
    for sel_group_id in sel_group_id_list:
        save_object(PermissionMapping(createtime=cur_time, updatetime=cur_time,\
            actor_type=Group.__name__, actor_id=sel_group_id,\
            res_type=Host.__name__, res_id=host_id))
    for group in del_group_list:
        query_objs = get_objects(PermissionMapping, \
            actor_type=Group.__name__, actor_id=group.id, \
            res_type=Host.__name__, res_id=host_id)
        if len(query_objs) == 1:
            delete_object(query_objs[0])
    #mapping between host and user
    for user in user_list:
        if str(user.id) in sel_user_id_list:
            sel_user_id_list.remove(str(user.id))
        else:
            del_user_list.append(user)
    for sel_user_id in sel_user_id_list:
        save_object(PermissionMapping(createtime=cur_time, updatetime=cur_time,\
            actor_type=User.__name__, actor_id=sel_user_id, \
            res_type=Host.__name__, res_id=host_id))
    for user in del_user_list:
        query_objs = get_objects(PermissionMapping, \
            actor_type=User.__name__, actor_id=user.id, \
            res_type=Host.__name__, res_id=host_id)
        if len(query_objs) == 1:
            delete_object(query_objs[0])
    return {'status':True, 'cause':''}


def change_group_perm(handler):
    logger.debug('model_util.change_group_perm')
    group_id = get_argument(handler, 'group_id')
    sel_system_id_list = get_arguments(handler, 'system_list')
    sel_host_id_list  = get_arguments(handler, 'host_list')
    group = get_object_by_id(Group, group_id)
    system_list = get_resources(Group, group_id, System)
    host_list   = get_resources(Group, group_id, Host)
    cur_time=datetime.datetime.now()
    del_system_list, del_host_list = [], []
    #mapping between group and system
    for sys_obj in system_list:
        if str(sys_obj.id) in sel_system_id_list:
            sel_system_id_list.remove(str(sys_obj.id))
        else:
            del_system_list.append(sys_obj)
    for sel_system_id in sel_system_id_list:
        save_object(PermissionMapping(createtime=cur_time, updatetime=cur_time,\
            res_type=System.__name__, res_id=sel_system_id, \
            actor_type=Group.__name__, actor_id=group_id))
    for sys_obj in del_system_list:
        query_objs = get_objects(PermissionMapping, \
            res_type=System.__name__, res_id=sys_obj.id, \
            actor_type=Group.__name__, actor_id=group_id)
        if len(query_objs) == 1:
            delete_object(query_objs[0])
    #mapping between group and host
    for host in host_list:
        if str(host.id) in sel_host_id_list:
            sel_host_id_list.remove(str(host.id))
        else:
            del_host_list.append(host)
    for sel_host_id in sel_host_id_list:
        save_object(PermissionMapping(createtime=cur_time, updatetime=cur_time,\
            res_type=Host.__name__, res_id=sel_host_id, \
            actor_type=Group.__name__, actor_id=group_id))
    for host in del_host_list:
        query_objs = get_objects(PermissionMapping, \
            res_type=Host.__name__, res_id=host.id, \
            actor_type=Group.__name__, actor_id=group_id)
        if len(query_objs) == 1:
            delete_object(query_objs[0])
    return {'status':True, 'cause':''}


def change_user_perm(handler):
    logger.debug('model_util.change_user_perm')
    user_id = get_argument(handler, 'user_id')
    sel_system_id_list = get_arguments(handler, 'system_list')
    sel_host_id_list   = get_arguments(handler, 'host_list')
    user = get_object_by_id(User, user_id)
    system_list = get_resources(User, user_id, System)
    host_list   = get_resources(User, user_id, Host)
    cur_time = datetime.datetime.now()
    del_system_list, del_host_list = [], []
    #mapping between group and system
    for sys_obj in system_list:
        if str(sys_obj.id) in sel_system_id_list:
            sel_system_id_list.remove(str(sys_obj.id))
        else:
            del_system_list.append(sys_obj)
    for sel_system_id in sel_system_id_list:
        save_object(PermissionMapping(createtime=cur_time, updatetime=cur_time,\
            res_type=System.__name__, res_id=sel_system_id, \
            actor_type=User.__name__, actor_id=user_id))
    for sys_obj in del_system_list:
        query_objs = get_objects(PermissionMapping, \
            res_type=System.__name__, res_id=sys_obj.id, \
            actor_type=User.__name__, actor_id=user_id)
        if len(query_objs) == 1:
            delete_object(query_objs[0])
    #mapping between group and host
    for host in host_list:
        if str(host.id) in sel_host_id_list:
            sel_host_id_list.remove(str(host.id))
        else:
            del_host_list.append(host)
    for sel_host_id in sel_host_id_list:
        save_object(PermissionMapping(createtime=cur_time, updatetime=cur_time,\
            res_type=Host.__name__, res_id=sel_host_id, \
            actor_type=User.__name__, actor_id=user_id))
    for host in del_host_list:
        query_objs = get_objects(PermissionMapping, \
            res_type=Host.__name__, res_id=host.id, \
            actor_type=User.__name__, actor_id=user_id)
        if len(query_objs) == 1:
            delete_object(query_objs[0])
    return {'status':True, 'cause':''}